package control

import "jvmgo/ch10/instructions/base"
import "jvmgo/ch10/rtda"

//void
type RETURN struct {
    base.NoOperandsInstruction
}

func (self *RETURN) Execute(frame *rtda.Frame) {
    frame.Thread().PopFrame()
}

//ref
type ARETURN struct {
    base.NoOperandsInstruction
}

func (self *ARETURN) Execute(frame *rtda.Frame) {
    thread := frame.Thread()
    currentFrame := thread.PopFrame()
    invokerFrame := thread.TopFrame()
    ref := currentFrame.OperandStack().PopRef()
    invokerFrame.OperandStack().PushRef(ref)
}

//double
type DRETURN struct {
    base.NoOperandsInstruction
}

func (self *DRETURN) Execute(frame *rtda.Frame) {
    thread := frame.Thread()
    currentFrame := thread.PopFrame()
    invokerFrame := thread.TopFrame()
    val := currentFrame.OperandStack().PopDouble()
    invokerFrame.OperandStack().PushDouble(val)
}

//float
type FRETURN struct {
    base.NoOperandsInstruction
}

func (self *FRETURN) Execute(frame *rtda.Frame) {
    thread := frame.Thread()
    currentFrame := thread.PopFrame()
    invokerFrame := thread.TopFrame()
    val := currentFrame.OperandStack().PopFloat()
    invokerFrame.OperandStack().PushFloat(val)
}

//int
type IRETURN struct {
    base.NoOperandsInstruction
}

func (self *IRETURN) Execute(frame *rtda.Frame) {
    thread := frame.Thread()
    currentFrame := thread.PopFrame()
    invokerFrame := thread.TopFrame()
    val := currentFrame.OperandStack().PopInt()
    invokerFrame.OperandStack().PushInt(val)
}

//long
type LRETURN struct {
    base.NoOperandsInstruction
}

func (self *LRETURN) Execute(frame *rtda.Frame) {
    thread := frame.Thread()
    currentFrame := thread.PopFrame()
    invokerFrame := thread.TopFrame()
    val := currentFrame.OperandStack().PopLong()
    invokerFrame.OperandStack().PushLong(val)
}